package jp.co.htkk.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import jp.co.htkk.dto.${TableName!}Dto;
import jp.co.htkk.dto.UserDto;
import jp.co.htkk.form.${TableName!}RegisterForm;
import jp.co.htkk.service.${TableName!}Service;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import java.util.UUID;

import static jp.co.htkk.common.CommonConst.REGISTER_${TABLENAME!};
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doReturn;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
@WebAppConfiguration
class ${TableName!}ControllerTest {
    private MockMvc mockMvc;
    private ObjectMapper mapper;
    @Autowired
    private WebApplicationContext webApplicationContext;

    @SpyBean
    private ${TableName!}Service ${tableName!}Service;

    @BeforeEach
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
        mapper = new ObjectMapper();
    }
    @Test
    void ${tableName!}Register() throws Exception {
        ${TableName!}RegisterForm registerForm = new ${TableName!}RegisterForm();
        registerForm.set${TableName!}Id("1");
        registerForm.setUserId("1");
        registerForm.setName("test");
        registerForm.setGender(0);
        registerForm.set${TableName!}birthExpectedDate("20200202");
        registerForm.setBirthDate("20200202");

        ${TableName!}Dto ${tableName!}Dto = new ${TableName!}Dto();
        ${tableName!}Dto.set${TableName!}Id(registerForm.get${TableName!}Id());
        ${tableName!}Dto.setUserId(registerForm.getUserId());
        ${tableName!}Dto.setName(registerForm.getName());
        ${tableName!}Dto.setGender(registerForm.getGender());
        ${tableName!}Dto.set${TableName!}birthExpectedDate(registerForm.get${TableName!}birthExpectedDate());

        given(${tableName!}Service.register(registerForm)).willReturn(${tableName!}Dto);

        mockMvc.perform(post(REGISTER_${TABLENAME!})
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(mapper.writeValueAsString(registerForm)))
                .andExpect(status().is2xxSuccessful())
                .andDo(print());
    }


    @Test
    void get${TableName!}ById() throws Exception {
        ${TableName!}Dto ${tableName!}Dto = new ${TableName!}Dto();
        ${tableName!}Dto.setId(1l);
        ${tableName!}Dto.set${TableName!}Id("1");
        ${tableName!}Dto.setUserId("1");
        ${tableName!}Dto.setName("test");
        ${tableName!}Dto.setGender(0);
        ${tableName!}Dto.set${TableName!}birthExpectedDate("20200202");
        ${tableName!}Dto.setBirthDate("20200202");
        doReturn(${tableName!}Dto).when(${tableName!}Service).get${TableName!}ById(any());

        mockMvc.perform(get("/api/${tableName!}/search/1")
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().is2xxSuccessful())
                .andDo(print());

    }

    @Test
    void delete${TableName!}ById() throws Exception {
        ${TableName!}Dto ${tableName!}Dto = new ${TableName!}Dto();
        ${tableName!}Dto.setId(1l);
        ${tableName!}Dto.set${TableName!}Id("1");
        ${tableName!}Dto.setUserId("1");
        ${tableName!}Dto.setName("test");
        ${tableName!}Dto.setGender(0);
        ${tableName!}Dto.set${TableName!}birthExpectedDate("20200202");
        ${tableName!}Dto.setBirthDate("20200202");
        doReturn(${tableName!}Dto).when(${tableName!}Service).delete${TableName!}ById(any());
        mockMvc.perform(delete("/api/${tableName!}/delete/1")
                        .contentType(MediaType.APPLICATION_JSON)
                )
                .andExpect(status().is2xxSuccessful())
                .andDo(print());
    }

    @Test
    void update${TableName!}() throws Exception {
        ${TableName!}Dto ${tableName!}Dto = new ${TableName!}Dto();
        ${tableName!}Dto.setId(1l);
        ${tableName!}Dto.set${TableName!}Id("1");
        ${tableName!}Dto.setUserId("1");
        ${tableName!}Dto.setName("test");
        ${tableName!}Dto.setGender(0);
        ${tableName!}Dto.set${TableName!}birthExpectedDate("20200202");
        ${tableName!}Dto.setBirthDate("20200202");
        String jsonStr = mapper.writeValueAsString(${tableName!}Dto);
        doReturn(${tableName!}Dto).when(${tableName!}Service).update${TableName!}(any());
        mockMvc.perform(put("/api/${tableName!}/update")
                        .content(jsonStr)
                        .contentType(MediaType.APPLICATION_JSON)
                )
                .andExpect(status().is2xxSuccessful())
                .andDo(print());
    }
}
